﻿/*
 * QtPet Online File Manager v1.0
 * Copyright (c) 2009, Zhifeng Lin (fszlin[at]gmail.com)
 * 
 * Licensed under the MS-PL license.
 * http://qtfile.codeplex.com/license
 */

using System;
using System.IO;
using System.Web;
using System.Linq;
using System.Resources;
using System.Reflection;
using System.Collections.Generic;

using QtFile.Services;

namespace QtFile.FileBased
{
    public class FileService : FileBasedService, IFileService
	{
		private static readonly ResourceManager mimeResource =
			new ResourceManager("QtFile.Resources.MimeTypes", Assembly.GetExecutingAssembly());

		public FileService(string rootPath, string username, bool encodeUserName, char directorySeparator)
			: base(rootPath, username, encodeUserName, directorySeparator)
		{
		}

        public OpResult Save(string folderPath, HttpPostedFileBase file, bool overWrite)
        {
			if (file == null)
				throw new ArgumentNullException("file");

			// Extrace file name, since FileName of the upload file maybe a full path (e.g. IE)
			string fileName = Path.GetFileName(file.FileName);

			string fullPath = RootFolder.GetPath(folderPath, fileName);

			if (!Directory.Exists(Path.GetDirectoryName(fullPath)))
				return OpResult.FolderNotFound;

            if (File.Exists(fullPath))
			{
				if (overWrite)
					File.Delete(fullPath);
				else
					return OpResult.AlreadyExist;
			}

            file.SaveAs(fullPath);
			return OpResult.Succeed;
        }

        public UserFile Retrieve(string path)
		{
			string fullPath = RootFolder.GetPath(path);
			FileInfo info = new FileInfo(fullPath);
			if (info.Exists)
				return new UserFile()
				{
					Path = fullPath,
					Name = info.Name,
					Size = info.Length,
					ContentType = GuessMime(info.Name),
					Modified = info.LastWriteTime
				};

			// file not found
			return null;
        }

		public OpResult Move(string srcPath, string destPath, bool overWrite)
		{
			srcPath = RootFolder.GetPath(srcPath);
			destPath = RootFolder.GetPath(destPath);

			if (!File.Exists(srcPath))
				return OpResult.NotFound;

			if (!Directory.Exists(Path.GetDirectoryName(destPath)))
				return OpResult.FolderNotFound;

			if (File.Exists(destPath))
			{
				if (overWrite)
					File.Delete(destPath);
				else
					return OpResult.AlreadyExist;
			}

			File.Move(srcPath, destPath);
			return OpResult.Succeed;
        }

		public OpResult Delete(string path)
		{
			string fullPath = RootFolder.GetPath(path);
			if (!File.Exists(fullPath))
				return OpResult.NotFound;

			File.Delete(fullPath);
			return OpResult.Succeed;
		}

		public IEnumerable<UserFileInfo> GetFileList(string path)
		{
			string fullPath = String.IsNullOrEmpty(path) ? RootFolder.RootPath : RootFolder.GetPath(path);
			if (!Directory.Exists(fullPath))
				return null;
			int fullPathLen = fullPath.Length + 1;

			var filePaths = Directory.GetFiles(fullPath);
			var files = new List<UserFileInfo>(filePaths.Length);
			foreach (var filePath in filePaths)
			{
				FileInfo file = new FileInfo(filePath);
				files.Add(new UserFileInfo()
				{
					Name = file.Name,
					Size = file.Length,
					ContentType = GuessMime(file.Name),
					Modified = file.LastWriteTimeUtc
				});

			}
			return files;
		}

		public int Count()
		{
			return RootFolder.CountFiles();
		}

		private static string GuessMime(string filePath)
		{
			var mime = mimeResource.GetString(Path.GetExtension(filePath).ToLower());
			return mime ?? "application/x-unknown-content-type";
		}
	}
}
